package com.sgzn.sgpay.service.impl;

import com.github.binarywang.wxpay.bean.entpay.*;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.EntPayService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.sgzn.sgpay.constants.WXInfoConstants;
import com.sgzn.sgpay.enums.EnumWeixinPayOrderStat;
import com.sgzn.sgpay.enums.EnumWithdrawStat;
import com.sgzn.sgpay.enums.SeqFlagEnum;
import com.sgzn.sgpay.enums.SgsResponseCode;
import com.sgzn.sgpay.exception.SgpayException;
import com.sgzn.sgpay.model.request.SgsMchAccountUpdateRequest;
import com.sgzn.sgpay.model.request.SgsMchWithdrawQueryPageRequest;
import com.sgzn.sgpay.model.request.SgsMerchantQueryBaseRequest;
import com.sgzn.sgpay.model.request.SgsWithdrawRequest;
import com.sgzn.sgpay.model.response.CurrentPageInfo;
import com.sgzn.sgpay.model.response.SgsResultResponse;
import com.sgzn.sgpay.model.response.result.MchWithdrawQueryPageResult;
import com.sgzn.sgpay.model.response.result.MerchantInfo;
import com.sgzn.sgpay.model.response.vo.WithdrawRecordVo;
import com.sgzn.sgpay.persistence.dao.TWithdrawRecordMapper;
import com.sgzn.sgpay.persistence.domain.TMerchant;
import com.sgzn.sgpay.persistence.domain.TWithdrawRecord;
import com.sgzn.sgpay.persistence.domain.TWithdrawRecordExample;
import com.sgzn.sgpay.persistence.manager.MerchantDaoManager;
import com.sgzn.sgpay.service.SgsMchAccountService;
import com.sgzn.sgpay.service.SgsMerchantQueryService;
import com.sgzn.sgpay.service.SgsWithdrawService;
import com.sgzn.sgpay.service.converter.AssembleSgsCommonHandle;
import com.sgzn.sgpay.service.support.SgsResponseUtil;
import com.sgzn.sgpay.util.*;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.WxMpUserQuery;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.result.WxMpUserList;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by xxjs-gd-llf
 * DATETIME:2018/5/23 22:22
 * Description:提现服务实现
 */
@Slf4j
@Service
public class SgsWithdrawServiceImpl implements SgsWithdrawService {
    @Autowired
    private SgsMerchantQueryService sgsMerchantQueryService;
    @Autowired
    private SgsMchAccountService sgsMchAccountService;

    @Autowired
    private MerchantDaoManager merchantDaoManager;

    @Autowired
    private TWithdrawRecordMapper tWithdrawRecordMapper;


    @Autowired
    private AssembleSgsCommonHandle assembleSgsCommonHandle;

    /**
     * 公众号服务
     */
    private WxMpService wxMpService = new WxMpServiceImpl();

    /**
     * 微信支付服务
     * @param
     * @return
     */
    private  WxPayService wxPayService = new WxPayServiceImpl();



    /**
     * 付款状态轮询
     */
    @Override
    public void checkEntBankPayOrder(){
        EntPayBankQueryResult entPayBankQueryResult = new EntPayBankQueryResult();

        //找到订单状态非成功的订单
        TWithdrawRecordExample tWithdrawRecordExample = new TWithdrawRecordExample();
        TWithdrawRecordExample.Criteria criteria = tWithdrawRecordExample.createCriteria();
        criteria.andWithdrawChannelEqualTo("02");
        criteria.andStateNotEqualTo(EnumWithdrawStat.S0S.getStateCode());
        List<TWithdrawRecord>  tWithdrawRecordList = new ArrayList<>();
        tWithdrawRecordList = tWithdrawRecordMapper.selectByExample(tWithdrawRecordExample);
        for ( TWithdrawRecord tWithdrawRecord : tWithdrawRecordList){
            entPayBankQueryResult = queryWeixinOrderState(tWithdrawRecord.getOrderId());
            if (entPayBankQueryResult.getStatus() == EnumWeixinPayOrderStat.SUCCESS.getStateDesc()){
                //微信查询状态为成功
            }else {
                //
            }
        }

    }

    /**
     * 根据商户订单号调用银行卡提现订单状态
     * @param merchantParterOrderNo
     * @return
     */
    private  EntPayBankQueryResult queryWeixinOrderState(String merchantParterOrderNo){
        //发起微信支付请求
        WxPayConfig wxPayConfig = new WxPayConfig();
        wxPayConfig.setAppId(WXInfoConstants.SGZN_WX_APP_ID);
        wxPayConfig.setMchId(WXInfoConstants.SGZN_WX_MCH_ID);
        wxPayConfig.setMchKey(WXInfoConstants.SGZN_WX_MCH_API_KEY);
        wxPayConfig.setKeyPath(WXInfoConstants.SGZN_WX_MCH_KEY_FILE_Path);
        wxPayService.setConfig( wxPayConfig );
        EntPayService entPayService = wxPayService.getEntPayService();
        try {
            return  entPayService.queryPayBank(merchantParterOrderNo);
        }catch (WxPayException w){
             w.printStackTrace();
        }
         return null;
    }

    /**
     * 提现记录分页查询
     * @param request
     * @return
     */
    @Override
   public SgsResultResponse<MchWithdrawQueryPageResult> queryMerchantWithdrawRecordPage(SgsMchWithdrawQueryPageRequest request){
        try{
            log.info("01 获取商户ID  mchId = {} ",request.getMchId() );
            //分页查询
            MchWithdrawQueryPageResult result = new MchWithdrawQueryPageResult();
            TWithdrawRecordExample example = this.getTWithdrawRecordExampleByPage(request);
            log.info("02 组装TWithdrawRecordExample = {} ",example );
            int totalCount = this.tWithdrawRecordMapper.countByExample(example);//获取总数
            log.info("03 查得商户提现记录总数 totalCount= {}",totalCount);

            CurrentPageInfo pageInfo = PageCalculator.getPageInfo(totalCount, request.getPageQueryParam().getPageSize(),
                    request.getPageQueryParam().getCurrentPage());
            StringBuffer clause = new StringBuffer();
            //加上起始和结束行号进行列表查询
            clause.append("merchant_id,created_at desc ");
            clause.append("limit ").append(pageInfo.getStartIndex()).
                    append(",").append(pageInfo.getPageSize());
            example.setOrderByClause(clause.toString());
            List<TWithdrawRecord> tWithdrawRecordList = tWithdrawRecordMapper.selectByExample(example);

            //对象转换
            List<WithdrawRecordVo> withdrawRecordVoList = new ArrayList<>();
            for (TWithdrawRecord tWithdrawRecord :tWithdrawRecordList ){
                WithdrawRecordVo withdrawRecordVo = new WithdrawRecordVo();
                withdrawRecordVo.setWithDrawchannel(tWithdrawRecord.getApplyReason());
                withdrawRecordVo.setWithDrawAmount(AmountTransUtil.centToYuan(tWithdrawRecord.getAmount(),0).toString() );
                withdrawRecordVo.setWithDrawTime(DateUtil.formatDate(tWithdrawRecord.getCreatedAt(),DateUtil.TIME_FORMAT_2));
                withdrawRecordVo.setWithDrawState(EnumWithdrawStat.getDescByCode(tWithdrawRecord.getState()));
                withdrawRecordVoList.add(withdrawRecordVo);
            }

            log.info("04 查得商户提现记录 withdrawRecordVoList {}",withdrawRecordVoList);
            result.setWithdrawRecordVoList(withdrawRecordVoList);
            result.setCurrentPage(pageInfo.getCurrentPage());
            result.setPageSize(pageInfo.getPageSize());
            result.setTotalCount(totalCount);
            result.setTotalPage(pageInfo.getTotalPage());
            return SgsResponseUtil.INSTANCE.success(result);
        }catch (Exception e){
            log.error("提现分页查询系统异常：",e);
            return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C503.getResponseCode(),SgsResponseCode.C503.getResponseDesc());
        }

    }


    /**
     * 获取查询对象
     * @param request
     * @return
     */
    private TWithdrawRecordExample  getTWithdrawRecordExampleByPage(SgsMchWithdrawQueryPageRequest request){
        TWithdrawRecordExample countExample = new TWithdrawRecordExample();
        TWithdrawRecordExample.Criteria cra = countExample.createCriteria();
        if(StringUtils.isNotBlank(request.getMchId())){
            cra.andMerchantIdEqualTo(request.getMchId());
        }
        return countExample;
    }

    /**
     * 提现到微信
     * @param sgsWithdrawRequest
     * @return
     */
    @Override
    public SgsResultResponse<Map<String, String>> withDrawWithWxTools(SgsWithdrawRequest sgsWithdrawRequest){

        log.info("SgsWithdrawServiceImpl 开始提现");
        SgsResultResponse sgsResponse = new SgsResultResponse();
        try{
            log.info("01 获取提现商户的OpenId");
            TMerchant tMerchant= getMerchantOpenIdForWithdraw(sgsWithdrawRequest.getMchId());

            log.info("02 检验商户提现金额是否大于可提现金额 ");
            SgsMerchantQueryBaseRequest sgsMerchantQueryBaseRequest = new SgsMerchantQueryBaseRequest();
            sgsMerchantQueryBaseRequest.setMchId(sgsWithdrawRequest.getMchId());
            assembleSgsCommonHandle.assemble(sgsWithdrawRequest, sgsMerchantQueryBaseRequest);
            SgsResultResponse<MerchantInfo> sgsResultResponse = sgsMerchantQueryService.queryMerchantInfo( sgsMerchantQueryBaseRequest);
            if ( sgsResultResponse != null ){
                if(  sgsResultResponse.getResult().getAccountAmount().compareTo(new BigDecimal(sgsWithdrawRequest.getAmount()) ) == -1 ){
                    log.error("商户余额不足");
                    return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C_MCH_BALANCE_NOT_ENOUGH.getResponseCode(),
                            SgsResponseCode.C_MCH_BALANCE_NOT_ENOUGH.getResponseDesc());
                }
            }

            log.info("03 提现额度校验 ");
            if( checkTodayWithdrawSum(sgsWithdrawRequest.getMchId(),sgsWithdrawRequest.getAmount() ) ==true ){
                log.error("今天提现金额超过额度20000");
                return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C_MCH_LIMIT_NOT_ENOUGH.getResponseCode(),
                        SgsResponseCode.C_MCH_LIMIT_NOT_ENOUGH.getResponseDesc());
            }

            //发起微信支付请求
            WxPayConfig wxPayConfig = new WxPayConfig();
            wxPayConfig.setAppId(WXInfoConstants.SGZN_WX_APP_ID);
            wxPayConfig.setMchId(WXInfoConstants.SGZN_WX_MCH_ID);
            wxPayConfig.setMchKey(WXInfoConstants.SGZN_WX_MCH_API_KEY);
            wxPayConfig.setKeyPath(WXInfoConstants.SGZN_WX_MCH_KEY_FILE_Path);
            wxPayService.setConfig( wxPayConfig );
            EntPayService entPayService = wxPayService.getEntPayService();

            EntPayRequest entPayRequest = assmbleEntPayRequest( sgsWithdrawRequest, tMerchant);

            TWithdrawRecord tWithdrawRecord = installWithdrawRecord( entPayRequest,sgsWithdrawRequest.getMchId());
            log.info("05 提现下单{}", tWithdrawRecord);

            EntPayResult entPayResult = entPayService.entPay(entPayRequest );
            log.info("06 提现下单响应{}", entPayResult);

            //结果为空
            if (entPayResult == null) {
                sgsResponse.setErrorCode(SgsResponseCode.C503000.getResponseCode());
                sgsResponse.setErrorMsg(SgsResponseCode.C503000.getResponseDesc());
                return sgsResponse;
            }

            //请求微信成功且支付成功
            if ("SUCCESS".equals(entPayResult.getReturnCode()) && "SUCCESS".equals(entPayResult.getResultCode())){
                //
                log.info("7 开始更新商户余额");
                updateMerchantAccountBalance(sgsWithdrawRequest);
                log.info("8 更新订单为成功状态");
               updateTwithdrawOrderSuccess(entPayResult, tWithdrawRecord.getOrderId() );
                //请求微信失败
            } else {
                log.info("9 更新订单为失败状态");
                updateTwithdrawOrderFail(entPayResult, tWithdrawRecord.getOrderId() );
                sgsResponse.setErrorCode(SgsResponseCode.C10013.getResponseCode());
                sgsResponse.setErrorMsg(SgsResponseCode.C10013.getResponseDesc());
                return sgsResponse;
            }
            //
            sgsResponse.setErrorCode(SgsResponseCode.C200.getResponseCode());
            sgsResponse.setErrorMsg(SgsResponseCode.C200.getResponseDesc());

        }catch (SgpayException e){
            log.error("微信下单业务异常：", e);
            sgsResponse.setErrorCode(e.getCode());
            sgsResponse.setErrorMsg(e.getDesc());
        } catch(Exception e ){
            e.printStackTrace();
        }
        log.info("10 完成商户提现申请{}",sgsResponse);
        return sgsResponse;
    }


    /**
     * 提现到银行卡
     */
    @Override
    public  SgsResultResponse<Map<String, String>> withDrawToBank(SgsWithdrawRequest sgsWithdrawRequest){

        log.info("SgsWithdrawServiceImpl 开始提现");
        SgsResultResponse sgsResponse = new SgsResultResponse();
        try{
            String merchantId = sgsWithdrawRequest.getMchId();
            log.info("01 获取提现商户的OpenId");
            TMerchant tMerchant= getMerchantOpenIdForWithdraw(merchantId);

            log.info("02 检验商户提现金额是否大于可提现金额 ");
            SgsMerchantQueryBaseRequest sgsMerchantQueryBaseRequest = new SgsMerchantQueryBaseRequest();
            sgsMerchantQueryBaseRequest.setMchId(merchantId);
            assembleSgsCommonHandle.assemble(sgsWithdrawRequest, sgsMerchantQueryBaseRequest);
            SgsResultResponse<MerchantInfo> sgsResultResponse = sgsMerchantQueryService.queryMerchantInfo( sgsMerchantQueryBaseRequest);
            if ( sgsResultResponse != null ){
                BigDecimal withdrawAmount = new BigDecimal(sgsWithdrawRequest.getAmount());
                BigDecimal withDrawFee = new BigDecimal(WXInfoConstants.WX_WITHDRAW_FEE_RATE); //手续费率
                if(  sgsResultResponse.getResult().getAccountAmount().compareTo( withdrawAmount.add(withdrawAmount.multiply(withDrawFee)) ) == -1 ){
                    log.error("商户余额不足");
                    return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C_MCH_BALANCE_NOT_ENOUGH.getResponseCode(),
                            SgsResponseCode.C_MCH_BALANCE_NOT_ENOUGH.getResponseDesc());
                }
            }

            log.info("03 提现额度校验 ");
            if( checkTodayWithdrawSum(merchantId,sgsWithdrawRequest.getAmount() ) ==true ){
                log.error("今天提现金额已超过额度20000");
                return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C_MCH_LIMIT_NOT_ENOUGH.getResponseCode(),
                        SgsResponseCode.C_MCH_LIMIT_NOT_ENOUGH.getResponseDesc());
            }

            //发起微信支付请求
            WxPayConfig wxPayConfig = new WxPayConfig();
            wxPayConfig.setAppId(WXInfoConstants.SGZN_WX_APP_ID);
            wxPayConfig.setMchId(WXInfoConstants.SGZN_WX_MCH_ID);
            wxPayConfig.setMchKey(WXInfoConstants.SGZN_WX_MCH_API_KEY);
            wxPayConfig.setKeyPath(WXInfoConstants.SGZN_WX_MCH_KEY_FILE_Path);
            wxPayService.setConfig( wxPayConfig );

            EntPayBankRequest entPayBankRequest = assmbleEntPayBankRequest( sgsWithdrawRequest, tMerchant );
            entPayBankRequest.setMchId( WXInfoConstants.SGZN_WX_MCH_ID );
            entPayBankRequest.setNonceStr( SeqUtil.getShortSeq(SeqFlagEnum.WX_RANDOM.getCode()));
            log.info("银行卡提现请求对象 EntPayBankRequest {} " ,entPayBankRequest );

            TWithdrawRecord tWithdrawRecord = installBankWithdrawRecord( entPayBankRequest,merchantId);
            if (tWithdrawRecord == null){
                log.info("05 银行卡提现下单失败{}");
                return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C_DB_EXCEPTION.getResponseCode(),
                        SgsResponseCode.C_DB_EXCEPTION.getResponseDesc());
            }
            log.info("05 银行卡提现下单成功{}", tWithdrawRecord);

            EntPayService entPayService = wxPayService.getEntPayService();
            EntPayBankResult entPayBankResult =  entPayService.payBank(entPayBankRequest );
            log.info("06 银行卡提现下单响应{}", entPayBankResult);

            //结果为空
            if (entPayBankResult == null) {
                sgsResponse.setErrorCode(SgsResponseCode.C503000.getResponseCode());
                sgsResponse.setErrorMsg(SgsResponseCode.C503000.getResponseDesc());
                return sgsResponse;
            }

            //请求微信成功且支付成功
            if ("SUCCESS".equals(entPayBankResult.getReturnCode()) && "SUCCESS".equals(entPayBankResult.getResultCode())){
                //
                log.info("7 银行卡提现开始更新商户余额");
                updateMerchantAccountBalance(sgsWithdrawRequest);
                log.info("8 银行卡提现更新订单为成功状态");
                updateTwithdrawBankOrderSuccess(entPayBankResult, tWithdrawRecord.getOrderId() );
                //请求微信失败
            } else {
                log.info("9 银行卡提现更新订单为失败状态");
                updateTwithdrawBankOrderFail(entPayBankResult, tWithdrawRecord.getOrderId() );
                sgsResponse.setErrorCode(SgsResponseCode.C10013.getResponseCode());
                sgsResponse.setErrorMsg(SgsResponseCode.C10013.getResponseDesc());
                return sgsResponse;
            }
            //
            sgsResponse.setErrorCode(SgsResponseCode.C200.getResponseCode());
            sgsResponse.setErrorMsg(SgsResponseCode.C200.getResponseDesc());

        }catch (SgpayException e){
            log.error("微信下单业务异常：", e);
            sgsResponse.setErrorCode(e.getCode());
            sgsResponse.setErrorMsg(e.getDesc());
        } catch(Exception e ){
            e.printStackTrace();
        }
        log.info("10 完成商户提现申请{}",sgsResponse);
        return sgsResponse;
    }


    /**
     * 生成加签签文
     * @param entPayRequest
     * @return
     */
    private String generateEntpaySign(EntPayRequest entPayRequest) {
        SortedMap<String, String> signParams = new TreeMap<String, String>();
        signParams.put("mch_appid",entPayRequest.getMchAppid());
        signParams.put("mchid",entPayRequest.getMchId());
        signParams.put("nonce_str", entPayRequest.getNonceStr());
        signParams.put("partner_trade_no",entPayRequest.getPartnerTradeNo());
        signParams.put("openid",entPayRequest.getOpenid());
        signParams.put("check_name",entPayRequest.getCheckName());
        signParams.put("re_user_name",entPayRequest.getReUserName());
        signParams.put("amount",entPayRequest.getAmount().toString() );
        signParams.put("desc",entPayRequest.getDescription());
        signParams.put("spbill_create_ip",entPayRequest.getSpbillCreateIp());
        return GenerateSignUtils.generateSign(signParams, WXInfoConstants.SGZN_WX_MCH_API_KEY);
    }


    /**
     * 组装微信请求对象
     * @param sgsWithdrawRequest
     * @param tMerchant
     * @return
     * @throws UnsupportedEncodingException
     */
    private EntPayRequest assmbleEntPayRequest(SgsWithdrawRequest sgsWithdrawRequest, TMerchant tMerchant) throws UnsupportedEncodingException {
        EntPayRequest entPayRequest = new EntPayRequest();
        entPayRequest.setMchAppid( WXInfoConstants.SGZN_WX_APP_ID);
        entPayRequest.setMchId( WXInfoConstants.SGZN_WX_MCH_ID );
        entPayRequest.setDeviceInfo("设备信息");
        entPayRequest.setNonceStr( SeqUtil.getShortSeq(SeqFlagEnum.WX_RANDOM.getCode()));
        entPayRequest.setPartnerTradeNo( SeqUtil.getShortSeq(SeqFlagEnum.WITHDRAW_ORDER_ID.getCode()));
        entPayRequest.setOpenid(tMerchant.getOpenId());
        entPayRequest.setCheckName("FORCE_CHECK");
        entPayRequest.setReUserName(tMerchant.getName());

        BigDecimal trsAmount = new BigDecimal(sgsWithdrawRequest.getAmount());
        String total_fee = AmountTransUtil.yuanToCents(trsAmount, 0);//微信的请求 金额单位为分
        entPayRequest.setAmount(Integer.parseInt(total_fee));
        entPayRequest.setDescription("企业付款到微信");
        entPayRequest.setSpbillCreateIp( IpUtils.getLocalhostIp() );
        entPayRequest.setSign( generateEntpaySign( entPayRequest ));

        return entPayRequest;

    }

    /**
     * 组装银行卡请求对象
     */

    private EntPayBankRequest assmbleEntPayBankRequest( SgsWithdrawRequest sgsWithdrawRequest, TMerchant tMerchant ){
        EntPayBankRequest.EntPayBankRequestBuilder  bankRequestBuilder = EntPayBankRequest.builder();
        bankRequestBuilder.partnerTradeNo(SeqUtil.getShortSeq(SeqFlagEnum.WITHDRAW_ORDER_ID.getCode()));
        bankRequestBuilder.encBankNo( tMerchant.getBankCardNo() );
        bankRequestBuilder.encTrueName(tMerchant.getBankAccountName());
        bankRequestBuilder.bankCode(tMerchant.getBankCardCode());
        BigDecimal trsAmount = new BigDecimal(sgsWithdrawRequest.getAmount());
        String total_fee = AmountTransUtil.yuanToCents(trsAmount, 0);//微信的请求 金额单位为分
        bankRequestBuilder.amount( Integer.parseInt(total_fee));
        bankRequestBuilder.description("商家提现到银行卡");
        return bankRequestBuilder.build();
    }

    /**
     * 微信提现下单
     * @Param entPayRequest
     */
    private TWithdrawRecord installWithdrawRecord(EntPayRequest entPayRequest ,String merchantId ){
        TWithdrawRecord tWithdrawRecord = new TWithdrawRecord();
        tWithdrawRecord.setOrderId(entPayRequest.getPartnerTradeNo() );
        tWithdrawRecord.setSgznWxMchId( entPayRequest.getMchId());
        tWithdrawRecord.setMerchantId(merchantId);
        tWithdrawRecord.setAccountName(entPayRequest.getReUserName());
        tWithdrawRecord.setAmount(new BigDecimal(entPayRequest.getAmount()));
        tWithdrawRecord.setState(EnumWithdrawStat.S0D.getStateCode()); //已受理
        tWithdrawRecord.setApplyReason(entPayRequest.getDescription());
        tWithdrawRecord.setCreatedAt(new Date());
        tWithdrawRecord.setCreatedBy(entPayRequest.getOpenid());
        tWithdrawRecord.setWithdrawChannel("01"); //提到微信
        tWithdrawRecordMapper.insert(tWithdrawRecord); //入库
        return tWithdrawRecord;
    }


    /**
     * 银行卡提现下单
     * @Param entPayRequest
     */
    private TWithdrawRecord installBankWithdrawRecord(EntPayBankRequest entPayBankRequest ,String merchantId ){
        TWithdrawRecord tWithdrawRecord = new TWithdrawRecord();
        tWithdrawRecord.setOrderId(entPayBankRequest.getPartnerTradeNo() );
        tWithdrawRecord.setSgznWxMchId( entPayBankRequest.getMchId());
        tWithdrawRecord.setMerchantId(merchantId);
        tWithdrawRecord.setAccountName(entPayBankRequest.getEncTrueName());
        tWithdrawRecord.setAmount(new BigDecimal(entPayBankRequest.getAmount()));
        tWithdrawRecord.setState(EnumWithdrawStat.S0D.getStateCode()); //已受理
        tWithdrawRecord.setApplyReason(entPayBankRequest.getDescription());
        tWithdrawRecord.setCreatedAt(new Date());
        tWithdrawRecord.setCreatedBy(entPayBankRequest.getEncTrueName());
        tWithdrawRecord.setWithdrawChannel("02"); //提到银行卡　
        int result = tWithdrawRecordMapper.insert(tWithdrawRecord); //入库
        if (result == 0 ){
            log.info("下单失败");
            return  null;

        }
        return tWithdrawRecord;
    }


    /**
     * 根据微信响应报文更新提现状态为成功
     * @Param entPayResult
     */
    private void updateTwithdrawBankOrderSuccess( EntPayBankResult entPayBankResult,String orderId ){
        TWithdrawRecordExample tWithdrawRecordExample = new TWithdrawRecordExample();
        TWithdrawRecordExample.Criteria criteria = tWithdrawRecordExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);

        TWithdrawRecord tWithdrawRecordTarget = new TWithdrawRecord();
        tWithdrawRecordTarget.setUpdatedAt(new Date());
        tWithdrawRecordTarget.setState(EnumWithdrawStat.S0S.getStateCode() );
        tWithdrawRecordTarget.setReturnCode(entPayBankResult.getReturnCode());
        tWithdrawRecordTarget.setResultCode(entPayBankResult.getResultCode());
        tWithdrawRecordTarget.setPaymentNo(entPayBankResult.getPaymentNo() );
        tWithdrawRecordTarget.setPaymentTime( new Date());
        tWithdrawRecordTarget.setErrCode(entPayBankResult.getErrCode());
        tWithdrawRecordTarget.setErrCodeDes(entPayBankResult.getErrCodeDes());
        tWithdrawRecordMapper.updateByExampleSelective( tWithdrawRecordTarget, tWithdrawRecordExample);
    }


    /**
     * 根据微信响应报文更新银行卡提现状态为失败
     */
    private void updateTwithdrawBankOrderFail( EntPayBankResult entPayBankResult,String orderId ){

        TWithdrawRecordExample tWithdrawRecordExample = new TWithdrawRecordExample();
        TWithdrawRecordExample.Criteria criteria = tWithdrawRecordExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);

        TWithdrawRecord tWithdrawRecordTarget = new TWithdrawRecord();
        tWithdrawRecordTarget.setUpdatedAt(new Date());
        tWithdrawRecordTarget.setState(EnumWithdrawStat.S0F.getStateCode() );
        tWithdrawRecordTarget.setReturnCode(entPayBankResult.getReturnCode());
        tWithdrawRecordTarget.setResultCode(entPayBankResult.getResultCode());
        tWithdrawRecordTarget.setPaymentNo(entPayBankResult.getPaymentNo());
        tWithdrawRecordTarget.setPaymentTime( new Date());
        tWithdrawRecordTarget.setErrCode(entPayBankResult.getErrCode());
        tWithdrawRecordTarget.setErrCodeDes(entPayBankResult.getErrCodeDes());
        log.info("更新提现状态为失败{}",tWithdrawRecordTarget);
        tWithdrawRecordMapper.updateByExampleSelective( tWithdrawRecordTarget, tWithdrawRecordExample);

    }

    /**
     * 根据微信响应报文更新提现状态为成功
     * @Param entPayResult
     */
    private void updateTwithdrawOrderSuccess( EntPayResult entPayResult,String orderId ){
        TWithdrawRecordExample tWithdrawRecordExample = new TWithdrawRecordExample();
        TWithdrawRecordExample.Criteria criteria = tWithdrawRecordExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);

        TWithdrawRecord tWithdrawRecordTarget = new TWithdrawRecord();
        tWithdrawRecordTarget.setUpdatedAt(new Date());
        tWithdrawRecordTarget.setState(EnumWithdrawStat.S0S.getStateCode() );
        tWithdrawRecordTarget.setReturnCode(entPayResult.getReturnCode());
        tWithdrawRecordTarget.setResultCode(entPayResult.getResultCode());
        tWithdrawRecordTarget.setPaymentNo(entPayResult.getPaymentNo() );
        tWithdrawRecordTarget.setPaymentTime( DateUtil.parseTimeFormat(entPayResult.getPaymentTime()));
        tWithdrawRecordTarget.setErrCode(entPayResult.getErrCode());
        tWithdrawRecordTarget.setErrCodeDes(entPayResult.getErrCodeDes());
        tWithdrawRecordMapper.updateByExampleSelective( tWithdrawRecordTarget, tWithdrawRecordExample);
    }


    /**
     * 根据微信响应报文更新提现状态为失败
     */
    private void updateTwithdrawOrderFail( EntPayResult entPayResult,String orderId ){

        TWithdrawRecordExample tWithdrawRecordExample = new TWithdrawRecordExample();
        TWithdrawRecordExample.Criteria criteria = tWithdrawRecordExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);

        TWithdrawRecord tWithdrawRecordTarget = new TWithdrawRecord();
        tWithdrawRecordTarget.setUpdatedAt(new Date());
        tWithdrawRecordTarget.setState(EnumWithdrawStat.S0F.getStateCode() );
        tWithdrawRecordTarget.setReturnCode(entPayResult.getReturnCode());
        tWithdrawRecordTarget.setResultCode(entPayResult.getResultCode());
        tWithdrawRecordTarget.setPaymentNo(entPayResult.getPaymentNo());
        tWithdrawRecordTarget.setPaymentTime( DateUtil.parseTimeFormat(entPayResult.getPaymentTime() ));
        tWithdrawRecordTarget.setErrCode(entPayResult.getErrCode());
        tWithdrawRecordTarget.setErrCodeDes(entPayResult.getErrCodeDes());
        log.info("更新提现状态为失败{}",tWithdrawRecordTarget);
        tWithdrawRecordMapper.updateByExampleSelective( tWithdrawRecordTarget, tWithdrawRecordExample);

    }
    /**
     * 更新商户账户余额
     */
    private void updateMerchantAccountBalance(SgsWithdrawRequest sgsWithdrawRequest){
        SgsMchAccountUpdateRequest sgsMchAccountUpdateRequest = new SgsMchAccountUpdateRequest();
        sgsMchAccountUpdateRequest.setMchId(sgsWithdrawRequest.getMchId() );
        sgsMchAccountUpdateRequest.setAmount( sgsWithdrawRequest.getAmount());
        sgsMchAccountUpdateRequest.setTradeMark("1"); //提现，商户账户余额减少
        sgsMchAccountUpdateRequest.setLoginChannel(sgsWithdrawRequest.getLoginChannel());
        sgsMchAccountUpdateRequest.setReqTime(new Date());
        sgsMchAccountUpdateRequest.setInitiationID(sgsWithdrawRequest.getInitiationID());
        sgsMchAccountService.updateAccountAmount( sgsMchAccountUpdateRequest );
    }


    /**
     * 获取提现商户的OpenId
     * @return
     */
    private TMerchant getMerchantOpenIdForWithdraw(String merchantId ){
        TMerchant tMerchant= merchantDaoManager.getMerchantByMerchId(merchantId);
        String microUnionId = tMerchant.getUnionid();
        String mpOpenId = getUnionIdFromMP(microUnionId);
        tMerchant.setOpenId(mpOpenId);
        return tMerchant;
    }

    /**
     * 根据UnionId获取公众号里的OpenId
     * @return
     */
    private String getUnionIdFromMP( String MicroUnionId ){
        WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();
        wxMpInMemoryConfigStorage.setAppId(WXInfoConstants.SGZN_WX_APP_ID); //设置微信公众号的appid
        wxMpInMemoryConfigStorage.setSecret(WXInfoConstants.SGZN_WX_MP_SECRET_KEY); // 设置微信公众号的app corpSecret
        wxMpInMemoryConfigStorage.setToken(WXInfoConstants.SGZN_WX_MP_WEIXIN_TOKEN); // 设置微信公众号的token
        wxMpInMemoryConfigStorage.setAesKey(WXInfoConstants.SGZN_WX_MP_WEIXIN_AESKEY); // 设置微信公众号的EncodingAESKey
        wxMpService.setWxMpConfigStorage(wxMpInMemoryConfigStorage);
        WxMpUserService wxMpUserService = wxMpService.getUserService();
        WxMpUserQuery wxMpUserQuery = new WxMpUserQuery();
        try {
            WxMpUserList wxMpUserList = wxMpUserService.userList("");//所有OpenId
            List<String> openIds = wxMpUserList.getOpenids();
            wxMpUserQuery.add(openIds);
            List<WxMpUser> wxMpUserUnionIdList =  wxMpUserService.userInfoList(wxMpUserQuery); //根据openIds找到所有用户(带UnionId)
            for (WxMpUser wxMpUser : wxMpUserUnionIdList ){
                String unionId  = wxMpUser.getUnionId();
                if(MicroUnionId.equals(unionId)){
                    log.info( "{}对应的商户号已经关注公众号",MicroUnionId);
                    return wxMpUser.getOpenId();
                }
            }
            log.info( "{}对应的商户号没有关注公众号,请先关注SGPay公众号",MicroUnionId);
        }catch (WxErrorException wxException ){
            wxException.printStackTrace();
            log.info( " 获取微信公众号用户列表失败");
            return "";
        }
        return  "";
    }



    /**
     * 商户当天提现总额是否超过20000
     * @param merchantId
     * @return
     */
    public Boolean checkTodayWithdrawSum(String merchantId,String amount ){
        TWithdrawRecordExample tWithdrawRecordExample = new TWithdrawRecordExample();
        TWithdrawRecordExample.Criteria criteria = tWithdrawRecordExample.createCriteria();
        criteria.andMerchantIdEqualTo(merchantId);

        Boolean isPassWithDrawSumLimit = false;
        int sumAmount = tWithdrawRecordMapper.countByExample(tWithdrawRecordExample );
        if( ( sumAmount  + Double.parseDouble(amount)) > 20000 ){
            isPassWithDrawSumLimit = true;
        }
        return isPassWithDrawSumLimit;
    }




}
